package com.songtech.base.universal.dao;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.List;

import javax.annotation.Resource;

import com.songtech.base.universal.dao.api.Mapper;
import com.songtech.base.universal.dao.api.beans.TableBeans;
import com.songtech.base.universal.dao.beans.Where;
import com.songtech.base.universal.dao.util.AbstractBaseDao;
import com.songtech.base.universal.dao.util.GetEntityParamUtil;
import com.songtech.base.universal.dao.util.ThrowsExceptionUtil;

/**
 * 通用dao
 * <br>使用方式一、
 * <br>直接使用基本数据访问的dao
 * <br>service中注入格式：@Resource(name = "com.songtech.basedao.model.BaseDaoTest")，
 * <br>com.songtech.basedao.model.BaseDaoTest是要注入的dao将会处理的entity对象
 * <br>使用方式二、
 * <br>在自己的dao中继承基本的dao
 * <br>service中注入格式：@Resource(name = "com.songtech.basedao.dao.impl.BaseDaoImpl")，
 * <br>com.songtech.basedao.dao.impl.BaseDaoImpl是dao对应的实现(要注入的实现类)
 * <br>dao需要使用泛型
 * <br>dao的实现继承基础dao和实现自定义的接口，自定义的接口要实现基础dao的接口
 * <br>使用方式三、
 * <br>在自己的dao中调用基本的dao
 * <br>dao的实现类需要使用 @Repository 注解
 * <br>在注入该dao的位置使用 @Resource(name = "xxx")注解，xxx：表示dao实现类的类名，首字母小写如：demoDaoImpl3
 * <br>该使用方式现不使用(没有开spring扫描)
 * @param <T>
 */
public class BaseDaoImpl<T extends Object> extends AbstractBaseDao implements BaseDao<T> {
	@Resource(name = "mapperImpl")
	private Mapper<T, Serializable> mapper;
	
	private TableBeans tableBeans;
	
	/**
	 * 通过工具DaoImplAutoCreator注册的bean class
	 */
	public void setEntityClass(Class<T> entityClass) {
		// 反射工具
		GetEntityParamUtil getParam = new GetEntityParamUtil();
		
		tableBeans = new TableBeans();
		tableBeans.setEntityClass(entityClass);
		tableBeans.setTableName(getParam.getTableName(entityClass));
		tableBeans.setSqlParms(getParam.getParamByBean(entityClass));
		// 从获取到的BeanParam list中获取主键
		tableBeans.setColumn(getParam.getParamById(tableBeans.getSqlParms()));
	}
	
	/**
	 * 通用dao类BaseDao
	 * <br>记录添加
	 * @param obj
	 * @return
	 * @throws SQLException 
	 */
	@Override
	public int insert(T obj) throws SQLException {
		ThrowsExceptionUtil.throwNullParametersException(obj);
		return mapper.insert(obj, tableBeans);
	}
	
	/**
	 * 通用dao类BaseDao
	 * <br>多条数据同时插入
	 * @param objs
	 * @return
	 * @throws SQLException 
	 */
	@Override
	public int insert(List<T> objs) throws SQLException {
		ThrowsExceptionUtil.throwNullParametersException(objs);
		return mapper.insert(objs, tableBeans);
	}
	
	/**
	 * 通用dao类BaseDao
	 * <br>记录添加(主键使用系统生成的UUID)
	 * @param obj
	 * @return
	 * @throws SQLException 
	 */
	@Override
	public int insertSetUUID(T obj) throws SQLException {
		ThrowsExceptionUtil.throwNullParametersException(obj);
		return mapper.insertSetUUID(obj, tableBeans);
	}
	
	/**
	 * 通用dao类BaseDao
	 * <br>多条数据同时插入(主键使用系统生成的UUID)
	 * @param objs
	 * @return
	 * @throws SQLException 
	 */
	@Override
	public int insertSetUUID(List<T> objs) throws SQLException {
		ThrowsExceptionUtil.throwNullParametersException(objs);
		return mapper.insertSetUUID(objs, tableBeans);
	}
	
	/**
	 * 通用dao类BaseDao
	 * <br>删除某个记录
	 * @param id 主键
	 * @return
	 * @throws SQLException 
	 */
	@Override
	public int delete(Serializable id) throws SQLException {
		ThrowsExceptionUtil.throwNullParametersException(id);
		return mapper.delete(id, tableBeans);
	}
	
	/**
	 * 通用dao类BaseDao
	 * <br>条件删除记录
	 * @param obj 条件对象
	 * @return
	 * @throws SQLException 
	 */
	@Override
	public int delete(T obj) throws SQLException {
		ThrowsExceptionUtil.throwNullParametersException(obj);
		return mapper.delete(obj, tableBeans);
	}
	
	/**
	 * 通用dao类BaseDao
	 * <br>条件删除记录
	 * @param where 条件对象
	 * @return
	 * @throws SQLException 
	 */
	@Override
	public int delete(Where where) throws SQLException {
		ThrowsExceptionUtil.throwNullParametersException(where);
		return mapper.delete(where, tableBeans);
	}
	
	/**
	 * 通用dao类BaseDao
	 * <br>更新不为null的字段
	 * <br>根据主键进行更新
	 * @param obj
	 * @return
	 * @throws SQLException 
	 */
	@Override
	public int updateNotEmpty(T obj) throws SQLException {
		ThrowsExceptionUtil.throwNullParametersException(obj);
		return mapper.updateNotEmpty(obj, tableBeans);
	}
	
	/**
	 * 通用dao类BaseDao
	 * <br>更新所有字段
	 * @param obj
	 * @return
	 * @throws SQLException 
	 */
	@Override
	public int update(T obj) throws SQLException {
		ThrowsExceptionUtil.throwNullParametersException(obj);
		return mapper.update(obj, tableBeans);
	}
	
	/**
	 * 通用dao类BaseDao
	 * <br>更新不为null的字段
	 * <br>根据主键进行更新
	 * @param obj
	 * @param where
	 * @return
	 * @throws SQLException 
	 */
	@Override
	public int updateNotEmpty(T obj, Where where) throws SQLException {
		ThrowsExceptionUtil.throwNullParametersException(obj);
		return mapper.updateNotEmpty(obj, where, tableBeans);
	}
	
	/**
	 * 通用dao类BaseDao
	 * <br>更新所有字段
	 * @param obj
	 * @param where
	 * @return
	 * @throws SQLException 
	 */
	@Override
	public int update(T obj, Where where) throws SQLException {
		ThrowsExceptionUtil.throwNullParametersException(obj);
		return mapper.update(obj, where, tableBeans);
	}
	
	/**
	 * 通用dao类BaseDao
	 * <br>通过主键获取记录
	 * @param id 主键
	 * @return Object
	 * @throws SQLException 
	 */
	@Override
	public T selectById(Serializable id) throws SQLException {
		ThrowsExceptionUtil.throwNullParametersException(id);
		return mapper.selectById(id, tableBeans);
	}
	
	/**
	 * 通用dao类BaseDao
	 * <br>获取记录
	 * @param obj 条件
	 * @return Object
	 * @throws SQLException 
	 */
	@Override
	public List<T> select(T obj) throws SQLException {
		ThrowsExceptionUtil.throwNullParametersException(obj);
		return mapper.selectList(obj, tableBeans);
	}
	
	/**
	 * 通用dao类BaseDao
	 * <br>获取记录
	 * @param where 条件
	 * @return Object
	 * @throws SQLException 
	 */
	@Override
	public List<T> select(Where where) throws SQLException {
		ThrowsExceptionUtil.throwNullParametersException(where);
		return mapper.selectList(where, tableBeans);
	}
}
